#/usr/bin/python
# -*- coding: utf-8 -*-

from elements import *
from mesh import DefaultMesh

eltype_to_modelclass = {
    'S3': Tri3(),
    'S4': Quad4(),
    'S6': Tri6(),
    'S8': Quad8(),
    'B2': Beam2(),
    'B3': Beam3(),
    'R2': Rod2(),          
}

class InterpMesh(DefaultMesh):
    
    def __init__(self, **kwargs):
        
        
        # mesh prop:
        self.ndofs_per_node = 6
        
        # Node entities:
        self.nodesCoo = []
        self.nodesElements = []
        self.nnodes = 0
        # Mapping of nodes:
        self.nodesMap = {"U2C": {}, "C2U": [],
                         "COO2C": {},"C2COO": []}
        # Element entities:
        self.elementsNodes = []
        self.elementsAO = []
        self.elementsFrame = []
        self.elementsProp = []
        self.elementsType = []
        # Mapping of elements:
        self.elementsMap = {"U2C": {}, "C2U": []}
        self.nElem = 0
        
        self.dofs = None
        self.enrichments = []
        self.enrichmentsMap = {"U2C": {}, "C2U": [],"C2DOF":[],"DOF2C":{}}
        self.subspaces = []
        self.subspacesMap = {"U2C": {}, "C2U": []} 
        
        args = self.__dict__ 
        
        for k in kwargs.keys():
            if k in args.keys():
                self.__setattr__(k,kwargs[k])
    
    def consolidateMesh(self):
        from copy import copy
        elementsMap = {"U2C": {}, "C2U": []}
        elementsNodes = []
        elementsType = []
        
        for id, elem in enumerate(self.elementsNodes):
            transform=False
            # eliminate non valid nodes in elements:
            elem = copy(elem)
            for i,nid in enumerate(elem):
                if nid not in self.nodesMap["C2U"]:
                    elem[i]=None
                    transform = True
            # transform element into manifold elements:
            if transform:
                elements, types = eltype_to_modelclass[self.elementsType[id]].degenerate(elem)
                eid = 0
                # In the case degenerate element is only one node:
                if not (elements and types):
                    continue
                # else:
                for elem,type in zip(elements,types):
                    cid = len(elementsNodes)
                    elementsNodes.append(elem)
                    elementsType.append(type)
                    uid = str(self.elementsMap["C2U"][id])+'.'+str(eid)
                    elementsMap["C2U"].append(uid)
                    elementsMap["U2C"][uid] = cid
                    eid+=1
            else:
                # untransformed element:
                cid = len(elementsNodes)
                elementsNodes.append(elem)
                elementsType.append(self.elementsType[id])
                elementsMap["C2U"].append(self.elementsMap["C2U"][id])
                elementsMap["U2C"][self.elementsMap["C2U"][id]] = cid
            
        self.elementsMap = elementsMap
        self.elementsNodes = elementsNodes
        self.elementsType = elementsType     
            
        self.buildDofs()    